package com.chuangke.sinotrukbudget.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.admin.data.builder.UserDataBuilder;
import com.chuangke.admin.model.SysDept;
import com.chuangke.admin.model.SysUser;
import com.chuangke.admin.service.SysDeptService;
import com.chuangke.admin.service.SysUserService;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.core.data.builder.DataBuildConfig;
import com.chuangke.core.data.builder.DataBuilder;
import com.chuangke.framework.model.BasicModel;
import com.chuangke.sinotrukbudget.data.builder.BudgetAccountBuilder;
import com.chuangke.sinotrukbudget.model.BudgetDeptAccount;
import com.chuangke.sinotrukbudget.sdao.BudgetDeptAccountDaoService;
import com.chuangke.sinotrukbudget.service.BudgetDeptAccountService;

/**
 * 部门科目对照 Service业务层处理
 *
 * @author chuangke
 * @date "2022-10-21"
 */
@Service
public class BudgetDeptAccountServiceImpl implements BudgetDeptAccountService {

    public static final String CACHE_NAME = "budget_dept_account";

    @Autowired
    private BudgetDeptAccountDaoService budgetDeptAccountDaoService;
    @Autowired
    private SysUserService SysUserService;
    @Autowired
    private SysDeptService sysDeptService;

    @CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
    @Override
    public boolean rsSave(String deptId, List<BudgetDeptAccount> records) {
        budgetDeptAccountDaoService
                .remove(new QueryWrapper<BudgetDeptAccount>().lambda().eq(BudgetDeptAccount::getDeptId, deptId));
        budgetDeptAccountDaoService.saveBatch(records);
        return true;
    }

    @CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
    @Override
    public boolean save(String deptId, List<BudgetDeptAccount> records) {
        if (!CollectionUtils.isEmpty(records)) {
            List<String> accountIdList = records.stream().map(BudgetDeptAccount::getAccountId)
                    .collect(Collectors.toList());
            budgetDeptAccountDaoService.remove(new QueryWrapper<BudgetDeptAccount>().lambda()
                    .eq(BudgetDeptAccount::getDeptId, deptId).in(BudgetDeptAccount::getAccountId, accountIdList));
            budgetDeptAccountDaoService.saveBatch(records);
        }
        return true;
    }

    @CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
    @Override
    public boolean delete(String deptId, List<String> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            budgetDeptAccountDaoService.remove(new QueryWrapper<BudgetDeptAccount>().lambda()
                    .eq(BudgetDeptAccount::getDeptId, deptId).in(BudgetDeptAccount::getId, ids));
        }
        return true;
    }

    @Cacheable(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
    public List<BudgetDeptAccount> listAll() {
        return budgetDeptAccountDaoService.list();
    }

    @Override
    public List<BudgetDeptAccount> listByDept(String deptId) {
        if (StrUtil.isBlank(deptId)) {
            return new ArrayList<>();
        }
//		List<BudgetDeptAccount> list = ((BudgetDeptAccountService) AopContext.currentProxy()).listAll();
//		List<BudgetDeptAccount> deptList = list.stream().filter(bda-> deptId.equals(bda.getDeptId())).collect(Collectors.toList()) ;
//		DataBuilder.of(deptList).appendBuilder(new BudgetAccountBuilder(), new DataBuildConfig("accountId", "accountName"))
//				.build();
//		DataBuilder.of(list).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
//				new DataBuildConfig("updatedBy", "updatedByName")).build();
//		return deptList;
        return this.listByDepts(Arrays.asList(deptId));
    }

    @Override
    public List<BudgetDeptAccount> listByDept(String deptId, String fuzzy) {
        if (StrUtil.isBlank(deptId)) {
            return new ArrayList<>();
        }
//		List<BudgetDeptAccount> list = ((BudgetDeptAccountService) AopContext.currentProxy()).listAll();
//		List<BudgetDeptAccount> deptList = list.stream().filter(bda-> deptId.equals(bda.getDeptId())).collect(Collectors.toList()) ;
//		DataBuilder.of(deptList).appendBuilder(new BudgetAccountBuilder(), new DataBuildConfig("accountId", "accountName"))
//				.build();
//		DataBuilder.of(list).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
//				new DataBuildConfig("updatedBy", "updatedByName")).build();
//		return deptList;
        List<BudgetDeptAccount> list = this.listByDepts(Arrays.asList(deptId));
        list = list.stream().filter(bda -> bda.getAccountId().contains(fuzzy) || bda.getAccountName().contains(fuzzy)).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<BudgetDeptAccount> listByDepts(List<String> deptIdList) {
        if (CollectionUtils.isEmpty(deptIdList)) {
            return new ArrayList<>();
        }

        List<BudgetDeptAccount> list = ((BudgetDeptAccountService) AopContext.currentProxy()).listAll();
        List<BudgetDeptAccount> deptList = list.stream().filter(bda -> deptIdList.contains(bda.getDeptId()))
                .collect(Collectors.toList());
        DataBuilder.of(deptList)
                .appendBuilder(new BudgetAccountBuilder(), new DataBuildConfig("accountId", "accountName")).build();
        DataBuilder.of(list).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
                new DataBuildConfig("updatedBy", "updatedByName")).build();
        return deptList;
    }

    @Override
    public List<BudgetDeptAccount> listByAccount(String accountId) {
        if (StrUtil.isBlank(accountId)) {
            return new ArrayList<>();
        }
        List<BudgetDeptAccount> list = ((BudgetDeptAccountService) AopContext.currentProxy()).listAll();
        List<BudgetDeptAccount> accountList = list.stream().filter(bda -> accountId.equals(bda.getAccountId()))
                .collect(Collectors.toList());
        DataBuilder.of(accountList)
                .appendBuilder(new BudgetAccountBuilder(), new DataBuildConfig("accountId", "accountName")).build();
        DataBuilder.of(list).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
                new DataBuildConfig("updatedBy", "updatedByName")).build();
        return accountList;
    }

    @Override
    public List<SysDept> listUserOwnCompyGuikou() {
        String userId = SecurityUtils.getUserId();
        SysUser user = SysUserService.findById(userId);
        SysDept dept = sysDeptService.findParent(user.getDeptId());

        if (dept == null) {
            return new ArrayList<>();
        }

        List<SysDept> deptList = sysDeptService.findAllChildren(Arrays.asList(dept.getId()));
        List<String> deptIdList = deptList.stream().map(BasicModel::getId).collect(Collectors.toList());
        List<BudgetDeptAccount> list = ((BudgetDeptAccountService) AopContext.currentProxy()).listAll();

        List<String> ownDeptIdList = list.stream().filter(bda -> deptIdList.contains(bda.getDeptId()))
                .map(BudgetDeptAccount::getDeptId).collect(Collectors.toList());

        Map<String, SysDept> deptMap = sysDeptService.findMap();

        return deptMap.values().stream().filter(d -> ownDeptIdList.contains(d.getId())).collect(Collectors.toList());
    }

}
